#include "static.h"
#include "view.h"
#include "render.h"
#include "texture.h"
#include "system.h"

#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlmemory.h>

typedef struct _STATIC
{
	char *text;
	ufoColor color;
	IMAGE imageText;
	UFO_Font font;
	UFO_Texture textureText; 
}STATIC;

int ufoStaticSetText(UFO_View view, const char *text)
{
	STATIC *pStatic = ufoViewGetUserData(view);
	if (!pStatic) {
		pStatic = malloc(sizeof(STATIC));
		memset(pStatic, 0, sizeof(STATIC));
		ufoViewSetUserData(view, pStatic);
	}

	if (pStatic && text) {
		int len = strlen(text);
		if (pStatic->text)
			free(pStatic->text);
		pStatic->text = malloc(len+1);
		strcpy(pStatic->text, text);

		if (pStatic->textureText) {
			ufoTextureDelete(pStatic->textureText);
			pStatic->textureText = 0;
		}
		ufoImageDelete(&pStatic->imageText);

		//internal_genarateTexture(view);
		ufoViewSetNeedPaint(view);
		{
			//ufoRect rect = {0};
			//ufoViewGetRect(view, &rect);
		}
		return 1;
	}
	return 0;
}

int ufoStaticSetColor(UFO_View view, ufoColor color)
{
	STATIC *pStatic = ufoViewGetUserData(view);
	if (pStatic) {
		pStatic->color = color;
		ufoViewSetNeedPaint(view);
		return 1;
	}
	return 0;
}

int ufoStaticSetFont(UFO_View view, UFO_Font font)
{
	STATIC *pStatic = ufoViewGetUserData(view);
	if (pStatic) {
		pStatic->font = font;
		ufoViewSetNeedPaint(view);
		return 1;
	}
	return 0;
}

int internal_genarateTexture(UFO_View view)
{
	STATIC *pStatic = ufoViewGetUserData(view);
	if (!pStatic) {
		pStatic = malloc(sizeof(STATIC));
		memset(pStatic, 0, sizeof(STATIC));
		ufoViewSetUserData(view, pStatic);
	}

	if (pStatic && !pStatic->textureText && pStatic->text) {

		unsigned char *textData = 0;
		ufoRect rcText = {0};
		int width, height;
		int size = 0;
        int bold = 0;
		if (pStatic->font) {
			size = ufoFontGetSize(pStatic->font);
            bold = ufoFontGetBold(pStatic->font);
        }
        
		ufoViewGetRect(view, &rcText);
		if (ufoViewGetMask(view, UFO_VIEW_BIT_AUTOSIZE)) {
			rcText.left = 0;
			rcText.top = 0;
			rcText.right = 88888888;
			rcText.bottom = 88888888;
		}

		ufoRectMoveTo(&rcText, 0, 0);
		ufoRenderText(pStatic->text, &rcText, 0, size, bold, pStatic->color, UFO_TEXT_CALCRECT, 0);
		
		width = rcText.right-rcText.left;
		height = rcText.bottom-rcText.top;
		textData = (unsigned char*)malloc(width*height*4);
		//memset(textData, 0xff, width*height*4);

		rcText.right = width;
		rcText.bottom = height;
		ufoRenderText(pStatic->text, &rcText, 0, size, bold, pStatic->color, 0, textData);

		ufoImageCreate(width, height, 4, textData, &pStatic->imageText);
		pStatic->textureText = ufoTextureCreate(&pStatic->imageText, 0);
		
		/*{
			TEXTUREMODE drawMode = {TEXTUREMODE_CENTER, 0, 0, 0, 0};
			drawMode.destRect.right = rcText.right/ufoGetDPI();
			drawMode.destRect.bottom = rcText.bottom/ufoGetDPI();
			ufoTextureSetMode(pStatic->textureText, &drawMode);
		}*/

		ufoSetTextureFilter(pStatic->imageText.id, UFO_TEXTURE_FILTER_POINT, 0);
		
		free(textData);
	}

	return 0;
}

int default_static_proc(UFO_View view, int id, void* wParam, void* lParam)
{
	STATIC *pStatic = ufoViewGetUserData(view);
	if (!pStatic) {
		pStatic = malloc(sizeof(STATIC));
		memset(pStatic, 0, sizeof(STATIC));
		ufoViewSetUserData(view, pStatic);
	}

	switch (id) {
	case MSG_XML:
		{
			{
				xmlNodePtr node = wParam;
				xmlChar *text = xmlGetProp(node, (const xmlChar*)"text");
				xmlChar *textColor = xmlGetProp(node, (const xmlChar*)"textColor");
				xmlChar *font = xmlGetProp(node, (const xmlChar*)"font");

				if (text) {
					ufoStaticSetText(view, text);
					xmlFree(text);
				}
                if (textColor) {
                    int red = 0, green = 0, blue = 0;
                    ufoColor color;
                    sscanf(textColor, "%d, %d, %d", &red, &green, &blue);
                    color.red = red/255.0f;
                    color.green = green/255.0f;
                    color.blue = green/255.0f;
                    color.alpha = 1.0f;
					ufoStaticSetColor(view, color);
					xmlFree(textColor);
				}
				if (font) {
					UFO_Font _font = ufoResourceGetFont(font);
					if (_font) {
						ufoStaticSetFont(view, _font);
					}
				}
			}
			ufoViewDefaultProc(view, id, wParam, lParam);
		}
		return 1;

	case MSG_CALC_SIZE:
		{
			internal_genarateTexture(view);

			{
				ufoSize* size = (ufoSize*)wParam;
				size->width = ufoTextureGetWidth(pStatic->textureText)/ufoGetDPI()+1.0f;
				size->height = ufoTextureGetHeight(pStatic->textureText)/ufoGetDPI()+1.0f;
				size = 0;
			}
		}
		break;

	case MSG_PAINT:
		{
			ufoViewDefaultProc(view, id, wParam, lParam);//### super 

			if (pStatic->text) {
				ufoRect dst = {0};					
				int width = 0;
				int height = 0;
				UFO_PAINT_STRUCT *paint = (UFO_PAINT_STRUCT *)lParam;
				ufoViewGetRect(view, &dst);

				internal_genarateTexture(view);

				width = ufoTextureGetWidth(pStatic->textureText);
				height = ufoTextureGetHeight(pStatic->textureText);

				dst.left *= ufoGetDPI();
				dst.top *= ufoGetDPI();
				dst.left = (int)(dst.left);
				dst.top = (int)(dst.top);

				dst.right = dst.left+width;
				dst.bottom = dst.top + height;

				dst.right = (int)(dst.right);
				dst.bottom = (int)(dst.bottom);

				ufoTextureDraw(0, pStatic->textureText, 0, &dst, paint->stencilTest, paint->color, paint->alpha, 1.0f);
			}
		}
		
		return 1;
	}

	return ufoViewDefaultProc(view, id, wParam, lParam);//### pass to default view proc
}